library(shiny)
Registered S3 methods overwritten by 'htmltools':
method from
print.html tools:rstudio
print.shiny.tag tools:rstudio
print.shiny.tag.list tools:rstudio
library(tidyverse)
Registered S3 methods overwritten by 'dbplyr':
method from
print.tbl_lazy
print.tbl_sql
── Attaching packages ────────────────────────────────────────────────────── tidyverse 1.3.2 ──✔ ggplot2 3.3.6 ✔ purrr 0.3.4
✔ tibble 3.1.8 ✔ dplyr 1.0.9
✔ tidyr 1.2.0 ✔ stringr 1.4.0
✔ readr 2.1.2 ✔ forcats 0.5.1── Conflicts ───────────────────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()
obps_df <- read_csv("../order-book-plot-find/cum_errors/resources/for_web_app/LKOH-GMKN-2007-10-08-09_obps.csv")
Rows: 394482 Columns: 12── Column specification ───────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (2): SECCODE, BUYSELL
dbl (9): NO, TIME, ORDERNO, ACTION, PRICE, VOLUME, TRADENO, TRADEPRICE, OBPLOTNO
date (1): DATE
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# obps_df <- read_csv("../order-book-plot-find/cum_errors/resources/for_web_app/LKOH-2007-10-08_obps.csv")
# obps_df <- read_csv("../order-book-plot-find/cum_errors/resources/for_web_app/s1_s2_2007_obps.csv")
obps_df <- obps_df %>%
mutate(TIME_S = TIME/1000)
obps_df
order_atts_cumsums_df <- read_csv("../order-book-plot-find/cum_errors/resources/for_web_app/LKOH-GMKN-2007-10-08-09_order_atts_cumsums.csv")
Rows: 394482 Columns: 32── Column specification ───────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (2): ATT, SECCODE
dbl (28): VAL, NO, OBPLOTNO, SHAREBAL, BPROFIT, SPROFIT, OBPMINTPRICE, OBPMAXTPRICE, CBOVO...
dttm (1): DATETIMEMLLS
date (1): DATE
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# order_atts_cumsums_df <- read_csv("../order-book-plot-find/cum_errors/resources/for_web_app/LKOH-2007-10-08_order_atts_cumsums.csv")
# order_atts_cumsums_df <- read_csv("../order-book-plot-find/cum_errors/resources/for_web_app/s1_s2_2007_order_atts_cumsums.csv")
order_atts_cumsums_df
obp_cum_atts_df <- read_csv("../order-book-plot-find/cum_errors/resources/for_web_app/LKOH-GMKN-2007-10-08-09_obp_cum_atts.csv")
Rows: 75021 Columns: 6── Column specification ───────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (3): SECCODE, BUYSELLOBP, TRADESNOTRADES
dbl (2): OBPLOTNO, TRADEVOL
date (1): DATE
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# obp_cum_atts_df <- read_csv("../order-book-plot-find/cum_errors/resources/for_web_app/LKOH-2007-10-08_obp_cum_atts.csv")
# obp_cum_atts_df <- read_csv("../order-book-plot-find/cum_errors/resources/for_web_app/s1_s2_2007_obp_cum_atts.csv")
obp_cum_atts_df
order_atts_cumsums_enhanced_df <- left_join(order_atts_cumsums_df,
obps_df %>% select(-OBPLOTNO, -SECCODE),
by = c("NO", "DATE")) %>%
select(NO, SECCODE, DATETIMEMLLS, PRICE, TRADEPRICE, VOLUME,
DATE, TIME_S, OBPLOTNO, ATT, VAL,
SHAREBAL, BPROFIT, SPROFIT, OBPMINTPRICE, OBPMAXTPRICE,
CBOVOLtdcs, CSOVOLtdcs, BOVOLtdcs, SOVOLtdcs, BTVOLtdcs, STVOLtdcs,
CBOVOLobpcs, CSOVOLobpcs, BOVOLobpcs, SOVOLobpcs, BTVOLobpcs, STVOLobpcs,
sobp, bobp, max_sobp_bobp, minus_max_sobp_bobp, stday, btday, max_std_btd,
minus_max_std_btd)
order_atts_cumsums_enhanced_df
obp_minmax_atts_df <- order_atts_cumsums_enhanced_df %>%
select(NO, SECCODE, DATE, OBPLOTNO, ATT,
DATETIMEMLLS, PRICE, TRADEPRICE) %>%
group_by(SECCODE, DATE, OBPLOTNO) %>%
summarise(OBPBEGIN = min(DATETIMEMLLS), OBPEND = max(DATETIMEMLLS),
OBPBEGINNO = min(NO), OBPENDNO = max(NO),
OBPMINPRICE = min(PRICE), OBPMAXPRICE = max(PRICE))
`summarise()` has grouped output by 'SECCODE', 'DATE'. You can override using the `.groups` argument.
obp_minmax_atts_df
obp_cum_minmax_atts_df <- left_join(obp_cum_atts_df,
obp_minmax_atts_df %>% select(SECCODE,
DATE,
OBPLOTNO,
OBPBEGIN,
OBPBEGINNO,
OBPENDNO,
OBPEND,
OBPMINPRICE,
OBPMAXPRICE),
by = c("SECCODE", "DATE", "OBPLOTNO")) %>%
select(SECCODE, DATE, OBPLOTNO, TRADEVOL, BUYSELLOBP,
OBPBEGIN, OBPEND, OBPBEGINNO, OBPENDNO, OBPMINPRICE, OBPMAXPRICE,
TRADESNOTRADES) #, BUYSELLYIELD, OBPTDVOLRATIO, MINMAXRATIO)
obp_cum_minmax_atts_df
oas_att_bst <- order_atts_cumsums_enhanced_df %>%
select(NO, SECCODE, DATE, OBPLOTNO, ATT, TRADEPRICE) %>%
filter(ATT == "BTVOL" | ATT == "STVOL")
oas_att_bst
obp_minmax_tradeprice <- function(seccode, date, obplotno,
obpbeginno, obpendno, tradesnotrades, minmax) {
# print(paste(length(seccode),
# length(date),
# length(obplotno),
# length(obpbeginno),
# length(obpendno),
# length(minmax)))
# print(paste(seccode, date, obplotno, obpbeginno, obpendno, minmax))
# seq(length(obplotno))
if(tradesnotrades == "Y") {
if (minmax == "min") {
mint <- min(oas_att_bst %>%
filter(SECCODE == seccode & DATE == date &
NO >= obpbeginno & NO <= obpendno) %>%
.$TRADEPRICE %>%
cummin())
# print(mint)
mint
} else if (minmax == "max") {
maxt <- max(oas_att_bst %>%
filter(SECCODE == seccode & DATE == date &
NO >= obpbeginno & NO <= obpendno) %>%
.$TRADEPRICE %>%
cummax())
# print(maxt)
maxt
} else {
print(paste0("min or max only, not ", minmax))
stop()
}
} else {
NA
}
}
vextor_to_obp_minmax_tradeprice <- function(seccode, date, obplotno,
obpbeginno, obpendno, tradesnotrades, minmax) {
tibble(seccode, date, obplotno, obpbeginno, obpendno, tradesnotrades,
minmax = rep(minmax, length(obplotno))) %>%
pmap(obp_minmax_tradeprice) %>%
unlist()
}
obp_cum_tprice_atts <- obp_cum_minmax_atts_df %>%
# sample_n(20) %>%
group_by(SECCODE, DATE) %>%
summarise(OBPLOTNO = OBPLOTNO,
OBPMINTRADEPRICE = vextor_to_obp_minmax_tradeprice(SECCODE,
DATE,
OBPLOTNO,
OBPBEGINNO,
OBPENDNO,
TRADESNOTRADES,
"min"),
OBPMAXTRADEPRICE = vextor_to_obp_minmax_tradeprice(SECCODE,
DATE,
OBPLOTNO,
OBPBEGINNO,
OBPENDNO,
TRADESNOTRADES,
"max"))
`summarise()` has grouped output by 'SECCODE', 'DATE'. You can override using the `.groups` argument.
obp_cum_tprice_atts
obp_cum_minmax_tpminmax_atts_df <- left_join(obp_cum_minmax_atts_df,
obp_cum_tprice_atts,
by = c("SECCODE", "DATE", "OBPLOTNO"))
obp_cum_minmax_tpminmax_atts_df
obp_cum_atts_enh_df <- inner_join(obp_cum_minmax_tpminmax_atts_df,
order_atts_cumsums_enhanced_df %>% select(SECCODE,
DATE,
OBPLOTNO,
BPROFIT,
SPROFIT),
by = c("SECCODE", "DATE", "OBPLOTNO")) %>%
select(SECCODE, DATE, OBPLOTNO, TRADEVOL, BUYSELLOBP,
BPROFIT, SPROFIT,
OBPBEGIN, OBPEND, OBPBEGINNO, OBPENDNO, OBPMINPRICE, OBPMAXPRICE,
OBPMINTRADEPRICE, OBPMAXTRADEPRICE, TRADESNOTRADES) %>% #, BUYSELLYIELD, OBPTDVOLRATIO, MINMAXRATIO) %>%
rename("seccode" = "SECCODE",
"ddate" = "DATE",
"obplotno" = "OBPLOTNO",
"tradevol" = "TRADEVOL",
"buysellobp" = "BUYSELLOBP",
"bprofit" = "BPROFIT",
"sprofit" = "SPROFIT",
"obpbegin" = "OBPBEGIN",
"obpend" = "OBPEND",
"obpbeginno" = "OBPBEGINNO",
"obpendno" = "OBPENDNO",
"obpminprice" = "OBPMINPRICE",
"obpmaxprice" = "OBPMAXPRICE",
"obpmintradeprice" = "OBPMINTRADEPRICE",
"obpmaxtradeprice" = "OBPMAXTRADEPRICE",
"bprofit" = "BPROFIT",
"sprofit" = "SPROFIT",
"tradesnotrades" = "TRADESNOTRADES") %>%
distinct()
obp_cum_atts_enh_df
td_vol_sum_df <- obp_cum_atts_enh_df %>%
group_by(seccode, ddate) %>%
summarise(tdvolsum = sum(tradevol))
`summarise()` has grouped output by 'seccode'. You can override using the `.groups` argument.
obp_cum_atts_enh_volarranged_df <- left_join(obp_cum_atts_enh_df,
td_vol_sum_df,
by = c("seccode", "ddate")) %>%
mutate(obpshareintd = tradevol / tdvolsum) %>%
select(-tdvolsum) %>%
arrange(seccode, ddate, desc(obpshareintd))
obp_cum_atts_enh_volarranged_df
options(digits.secs = 3)
obp_cum_atts_enh_volarranged_df %>%
write_csv("../order-book-plot-find/cum_errors/resources/for_web_app/obp_cum_atts_enh_df.csv",
na = "")
order_atts_cumsums_enh2_df <- order_atts_cumsums_enhanced_df %>%
mutate(pcolor = if_else(ATT == "BOVOL",
"aquamarine",
if_else(ATT == "SOVOL",
"coral",
"#004481")),
pshape = 4L,
psize = 0.5)
order_atts_cumsums_enh2_df
order_atts_cumsums_enh4_df <- order_atts_cumsums_enh2_df %>%
arrange(SECCODE, DATE, NO) %>%
rename("nno" = "NO",
"seccode" = "SECCODE",
"datetimemlls" = "DATETIMEMLLS",
"price" = "PRICE",
"tradeprice" = "TRADEPRICE",
"volume" = "VOLUME",
"ddate" = "DATE",
"ttime_s" = "TIME_S",
"obplotno" = "OBPLOTNO",
"att" = "ATT",
"val" = "VAL",
"sharebal" = "SHAREBAL") %>%
select(-BPROFIT, -SPROFIT, -OBPMINTPRICE, -OBPMAXTPRICE)
# options(digits.secs = 3)
order_atts_cumsums_enh4_df %>%
write_csv("../order-book-plot-find/cum_errors/resources/for_web_app/order_atts_cumsums_enh4_df.csv",
na = "")
order_atts_cumsums_enh4_df
order_atts_cumsums_enh4_df %>%
filter(obplotno == 48851, att == "STVOL") %>%
select(nno, price, att, tradeprice, sobp, bobp)
LS0tDQp0aXRsZTogInByZXBhcmVfYmFsX3Rlc3RpbmdfZGZzIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KDQpgYGB7cn0NCmxpYnJhcnkoc2hpbnkpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmBgYA0KYGBge3J9DQpvYnBzX2RmIDwtIHJlYWRfY3N2KCIuLi9vcmRlci1ib29rLXBsb3QtZmluZC9jdW1fZXJyb3JzL3Jlc291cmNlcy9mb3Jfd2ViX2FwcC9MS09ILUdNS04tMjAwNy0xMC0wOC0wOV9vYnBzLmNzdiIpDQojIG9icHNfZGYgPC0gcmVhZF9jc3YoIi4uL29yZGVyLWJvb2stcGxvdC1maW5kL2N1bV9lcnJvcnMvcmVzb3VyY2VzL2Zvcl93ZWJfYXBwL0xLT0gtMjAwNy0xMC0wOF9vYnBzLmNzdiIpDQojIG9icHNfZGYgPC0gcmVhZF9jc3YoIi4uL29yZGVyLWJvb2stcGxvdC1maW5kL2N1bV9lcnJvcnMvcmVzb3VyY2VzL2Zvcl93ZWJfYXBwL3MxX3MyXzIwMDdfb2Jwcy5jc3YiKQ0Kb2Jwc19kZiA8LSBvYnBzX2RmICU+JSANCiAgbXV0YXRlKFRJTUVfUyA9IFRJTUUvMTAwMCkNCm9icHNfZGYNCmBgYA0KDQoNCmBgYHtyfQ0Kb3JkZXJfYXR0c19jdW1zdW1zX2RmIDwtIHJlYWRfY3N2KCIuLi9vcmRlci1ib29rLXBsb3QtZmluZC9jdW1fZXJyb3JzL3Jlc291cmNlcy9mb3Jfd2ViX2FwcC9MS09ILUdNS04tMjAwNy0xMC0wOC0wOV9vcmRlcl9hdHRzX2N1bXN1bXMuY3N2IikNCiMgb3JkZXJfYXR0c19jdW1zdW1zX2RmIDwtIHJlYWRfY3N2KCIuLi9vcmRlci1ib29rLXBsb3QtZmluZC9jdW1fZXJyb3JzL3Jlc291cmNlcy9mb3Jfd2ViX2FwcC9MS09ILTIwMDctMTAtMDhfb3JkZXJfYXR0c19jdW1zdW1zLmNzdiIpDQojIG9yZGVyX2F0dHNfY3Vtc3Vtc19kZiA8LSByZWFkX2NzdigiLi4vb3JkZXItYm9vay1wbG90LWZpbmQvY3VtX2Vycm9ycy9yZXNvdXJjZXMvZm9yX3dlYl9hcHAvczFfczJfMjAwN19vcmRlcl9hdHRzX2N1bXN1bXMuY3N2IikNCm9yZGVyX2F0dHNfY3Vtc3Vtc19kZg0KYGBgDQoNCmBgYHtyfQ0Kb2JwX2N1bV9hdHRzX2RmIDwtIHJlYWRfY3N2KCIuLi9vcmRlci1ib29rLXBsb3QtZmluZC9jdW1fZXJyb3JzL3Jlc291cmNlcy9mb3Jfd2ViX2FwcC9MS09ILUdNS04tMjAwNy0xMC0wOC0wOV9vYnBfY3VtX2F0dHMuY3N2IikNCiMgb2JwX2N1bV9hdHRzX2RmIDwtIHJlYWRfY3N2KCIuLi9vcmRlci1ib29rLXBsb3QtZmluZC9jdW1fZXJyb3JzL3Jlc291cmNlcy9mb3Jfd2ViX2FwcC9MS09ILTIwMDctMTAtMDhfb2JwX2N1bV9hdHRzLmNzdiIpDQojIG9icF9jdW1fYXR0c19kZiA8LSByZWFkX2NzdigiLi4vb3JkZXItYm9vay1wbG90LWZpbmQvY3VtX2Vycm9ycy9yZXNvdXJjZXMvZm9yX3dlYl9hcHAvczFfczJfMjAwN19vYnBfY3VtX2F0dHMuY3N2IikNCm9icF9jdW1fYXR0c19kZg0KYGBgDQoNCmBgYHtyfQ0Kb3JkZXJfYXR0c19jdW1zdW1zX2VuaGFuY2VkX2RmIDwtIGxlZnRfam9pbihvcmRlcl9hdHRzX2N1bXN1bXNfZGYsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYnBzX2RmICU+JSBzZWxlY3QoLU9CUExPVE5PLCAtU0VDQ09ERSksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieSA9IGMoIk5PIiwgIkRBVEUiKSkgJT4lIA0KICBzZWxlY3QoTk8sIFNFQ0NPREUsIERBVEVUSU1FTUxMUywgUFJJQ0UsIFRSQURFUFJJQ0UsIFZPTFVNRSwgDQogICAgICAgICBEQVRFLCBUSU1FX1MsIE9CUExPVE5PLCBBVFQsIFZBTCwgDQogICAgICAgICBTSEFSRUJBTCwgQlBST0ZJVCwgU1BST0ZJVCwgT0JQTUlOVFBSSUNFLCBPQlBNQVhUUFJJQ0UsDQogICAgICAgICBDQk9WT0x0ZGNzLCBDU09WT0x0ZGNzLCBCT1ZPTHRkY3MsIFNPVk9MdGRjcywgQlRWT0x0ZGNzLCBTVFZPTHRkY3MsIA0KICAgICAgICAgQ0JPVk9Mb2JwY3MsIENTT1ZPTG9icGNzLCBCT1ZPTG9icGNzLCBTT1ZPTG9icGNzLCBCVFZPTG9icGNzLCBTVFZPTG9icGNzLA0KICAgICAgICAgc29icCwgYm9icCwgbWF4X3NvYnBfYm9icCwgbWludXNfbWF4X3NvYnBfYm9icCwgc3RkYXksIGJ0ZGF5LCBtYXhfc3RkX2J0ZCwNCiAgICAgICAgIG1pbnVzX21heF9zdGRfYnRkKQ0Kb3JkZXJfYXR0c19jdW1zdW1zX2VuaGFuY2VkX2RmDQpgYGANCg0KYGBge3J9DQpvYnBfbWlubWF4X2F0dHNfZGYgPC0gb3JkZXJfYXR0c19jdW1zdW1zX2VuaGFuY2VkX2RmICU+JSANCiAgc2VsZWN0KE5PLCBTRUNDT0RFLCBEQVRFLCBPQlBMT1ROTywgQVRULA0KICAgICAgICAgREFURVRJTUVNTExTLCBQUklDRSwgVFJBREVQUklDRSkgJT4lIA0KICBncm91cF9ieShTRUNDT0RFLCBEQVRFLCBPQlBMT1ROTykgJT4lIA0KICBzdW1tYXJpc2UoT0JQQkVHSU4gPSBtaW4oREFURVRJTUVNTExTKSwgT0JQRU5EID0gbWF4KERBVEVUSU1FTUxMUyksIA0KICAgICAgICAgICAgT0JQQkVHSU5OTyA9IG1pbihOTyksIE9CUEVORE5PID0gbWF4KE5PKSwNCiAgICAgICAgICAgIE9CUE1JTlBSSUNFID0gbWluKFBSSUNFKSwgT0JQTUFYUFJJQ0UgPSBtYXgoUFJJQ0UpKQ0Kb2JwX21pbm1heF9hdHRzX2RmDQpgYGANCg0KYGBge3J9DQpvYnBfY3VtX21pbm1heF9hdHRzX2RmIDwtIGxlZnRfam9pbihvYnBfY3VtX2F0dHNfZGYsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JwX21pbm1heF9hdHRzX2RmICU+JSBzZWxlY3QoU0VDQ09ERSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERBVEUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQlBMT1ROTywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9CUEJFR0lOLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0JQQkVHSU5OTywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9CUEVORE5PLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0JQRU5ELA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0JQTUlOUFJJQ0UsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQlBNQVhQUklDRSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieSA9IGMoIlNFQ0NPREUiLCAiREFURSIsICJPQlBMT1ROTyIpKSAlPiUgDQogIHNlbGVjdChTRUNDT0RFLCBEQVRFLCBPQlBMT1ROTywgVFJBREVWT0wsIEJVWVNFTExPQlAsDQogICAgICAgICBPQlBCRUdJTiwgT0JQRU5ELCBPQlBCRUdJTk5PLCBPQlBFTkROTywgT0JQTUlOUFJJQ0UsIE9CUE1BWFBSSUNFLA0KICAgICAgICAgVFJBREVTTk9UUkFERVMpICMsIEJVWVNFTExZSUVMRCwgT0JQVERWT0xSQVRJTywgTUlOTUFYUkFUSU8pDQpvYnBfY3VtX21pbm1heF9hdHRzX2RmDQpgYGANCg0KYGBge3J9DQpvYXNfYXR0X2JzdCA8LSBvcmRlcl9hdHRzX2N1bXN1bXNfZW5oYW5jZWRfZGYgJT4lIA0KICBzZWxlY3QoTk8sIFNFQ0NPREUsIERBVEUsIE9CUExPVE5PLCBBVFQsIFRSQURFUFJJQ0UpICU+JSANCiAgZmlsdGVyKEFUVCA9PSAiQlRWT0wiIHwgQVRUID09ICJTVFZPTCIpDQpvYXNfYXR0X2JzdA0KYGBgDQoNCmBgYHtyfQ0Kb2JwX21pbm1heF90cmFkZXByaWNlIDwtIGZ1bmN0aW9uKHNlY2NvZGUsIGRhdGUsIG9icGxvdG5vLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYnBiZWdpbm5vLCBvYnBlbmRubywgdHJhZGVzbm90cmFkZXMsIG1pbm1heCkgew0KICAjIHByaW50KHBhc3RlKGxlbmd0aChzZWNjb2RlKSwNCiAgIyAgICAgICAgICAgICBsZW5ndGgoZGF0ZSksDQogICMgICAgICAgICAgICAgbGVuZ3RoKG9icGxvdG5vKSwNCiAgIyAgICAgICAgICAgICBsZW5ndGgob2JwYmVnaW5ubyksDQogICMgICAgICAgICAgICAgbGVuZ3RoKG9icGVuZG5vKSwNCiAgIyAgICAgICAgICAgICBsZW5ndGgobWlubWF4KSkpDQogICMgcHJpbnQocGFzdGUoc2VjY29kZSwgZGF0ZSwgb2JwbG90bm8sIG9icGJlZ2lubm8sIG9icGVuZG5vLCBtaW5tYXgpKQ0KICAjIHNlcShsZW5ndGgob2JwbG90bm8pKQ0KICBpZih0cmFkZXNub3RyYWRlcyA9PSAiWSIpIHsNCiAgICBpZiAobWlubWF4ID09ICJtaW4iKSB7DQogICAgICBtaW50IDwtIG1pbihvYXNfYXR0X2JzdCAlPiUNCiAgICAgICAgICAgICAgICAgICAgZmlsdGVyKFNFQ0NPREUgPT0gc2VjY29kZSAmIERBVEUgPT0gZGF0ZSAmIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOTyA+PSBvYnBiZWdpbm5vICYgTk8gPD0gb2JwZW5kbm8pICU+JSANCiAgICAgICAgICAgICAgICAgICAgLiRUUkFERVBSSUNFICU+JQ0KICAgICAgICAgICAgICAgICAgICBjdW1taW4oKSkNCiAgICAgICMgcHJpbnQobWludCkNCiAgICAgIG1pbnQNCiAgICB9IGVsc2UgaWYgKG1pbm1heCA9PSAibWF4Iikgew0KICAgICAgbWF4dCA8LSBtYXgob2FzX2F0dF9ic3QgJT4lDQogICAgICAgICAgICAgICAgICAgIGZpbHRlcihTRUNDT0RFID09IHNlY2NvZGUgJiBEQVRFID09IGRhdGUgJiANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTk8gPj0gb2JwYmVnaW5ubyAmIE5PIDw9IG9icGVuZG5vKSAlPiUgDQogICAgICAgICAgICAgICAgICAgIC4kVFJBREVQUklDRSAlPiUNCiAgICAgICAgICAgICAgICAgICAgY3VtbWF4KCkpDQogICAgICAjIHByaW50KG1heHQpDQogICAgICBtYXh0DQogICAgICANCiAgICB9IGVsc2Ugew0KICAgICAgcHJpbnQocGFzdGUwKCJtaW4gb3IgbWF4IG9ubHksIG5vdCAiLCBtaW5tYXgpKQ0KICAgICAgc3RvcCgpDQogICAgfQ0KICB9IGVsc2Ugew0KICAgIE5BDQogIH0NCn0NCmBgYA0KDQpgYGB7cn0NCnZleHRvcl90b19vYnBfbWlubWF4X3RyYWRlcHJpY2UgPC0gZnVuY3Rpb24oc2VjY29kZSwgZGF0ZSwgb2JwbG90bm8sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYnBiZWdpbm5vLCBvYnBlbmRubywgdHJhZGVzbm90cmFkZXMsIG1pbm1heCkgew0KICB0aWJibGUoc2VjY29kZSwgZGF0ZSwgb2JwbG90bm8sIG9icGJlZ2lubm8sIG9icGVuZG5vLCB0cmFkZXNub3RyYWRlcywNCiAgICAgICAgIG1pbm1heCA9IHJlcChtaW5tYXgsIGxlbmd0aChvYnBsb3RubykpKSAlPiUgDQogICAgcG1hcChvYnBfbWlubWF4X3RyYWRlcHJpY2UpICU+JSANCiAgICB1bmxpc3QoKQ0KfQ0KYGBgDQoNCmBgYHtyfQ0Kb2JwX2N1bV90cHJpY2VfYXR0cyA8LSBvYnBfY3VtX21pbm1heF9hdHRzX2RmICU+JSANCiAgIyBzYW1wbGVfbigyMCkgJT4lIA0KICBncm91cF9ieShTRUNDT0RFLCBEQVRFKSAlPiUgDQogIHN1bW1hcmlzZShPQlBMT1ROTyA9IE9CUExPVE5PLA0KICAgICAgICAgICAgT0JQTUlOVFJBREVQUklDRSA9IHZleHRvcl90b19vYnBfbWlubWF4X3RyYWRlcHJpY2UoU0VDQ09ERSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERBVEUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQlBMT1ROTywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9CUEJFR0lOTk8sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQlBFTkROTywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSQURFU05PVFJBREVTLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1pbiIpLA0KICAgICAgICAgICAgT0JQTUFYVFJBREVQUklDRSA9IHZleHRvcl90b19vYnBfbWlubWF4X3RyYWRlcHJpY2UoU0VDQ09ERSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERBVEUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQlBMT1ROTywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9CUEJFR0lOTk8sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQlBFTkROTywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSQURFU05PVFJBREVTLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1heCIpKQ0Kb2JwX2N1bV90cHJpY2VfYXR0cw0KYGBgDQoNCmBgYHtyfQ0Kb2JwX2N1bV9taW5tYXhfdHBtaW5tYXhfYXR0c19kZiA8LSBsZWZ0X2pvaW4ob2JwX2N1bV9taW5tYXhfYXR0c19kZiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9icF9jdW1fdHByaWNlX2F0dHMsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieSA9IGMoIlNFQ0NPREUiLCAiREFURSIsICJPQlBMT1ROTyIpKQ0Kb2JwX2N1bV9taW5tYXhfdHBtaW5tYXhfYXR0c19kZg0KYGBgDQoNCmBgYHtyfQ0Kb2JwX2N1bV9hdHRzX2VuaF9kZiA8LSBpbm5lcl9qb2luKG9icF9jdW1fbWlubWF4X3RwbWlubWF4X2F0dHNfZGYsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJfYXR0c19jdW1zdW1zX2VuaGFuY2VkX2RmICU+JSBzZWxlY3QoU0VDQ09ERSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEQVRFLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9CUExPVE5PLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJQUk9GSVQsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1BST0ZJVCksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnkgPSBjKCJTRUNDT0RFIiwgIkRBVEUiLCAiT0JQTE9UTk8iKSkgJT4lIA0KICBzZWxlY3QoU0VDQ09ERSwgREFURSwgT0JQTE9UTk8sIFRSQURFVk9MLCBCVVlTRUxMT0JQLA0KICAgICAgICAgQlBST0ZJVCwgU1BST0ZJVCwNCiAgICAgICAgIE9CUEJFR0lOLCBPQlBFTkQsIE9CUEJFR0lOTk8sIE9CUEVORE5PLCBPQlBNSU5QUklDRSwgT0JQTUFYUFJJQ0UsDQogICAgICAgICBPQlBNSU5UUkFERVBSSUNFLCBPQlBNQVhUUkFERVBSSUNFLCBUUkFERVNOT1RSQURFUykgJT4lICMsIEJVWVNFTExZSUVMRCwgT0JQVERWT0xSQVRJTywgTUlOTUFYUkFUSU8pICU+JSANCiAgcmVuYW1lKCJzZWNjb2RlIiA9ICJTRUNDT0RFIiwNCiAgICAgICAgICJkZGF0ZSIgPSAiREFURSIsDQogICAgICAgICAib2JwbG90bm8iID0gIk9CUExPVE5PIiwNCiAgICAgICAgICJ0cmFkZXZvbCIgPSAiVFJBREVWT0wiLA0KICAgICAgICAgImJ1eXNlbGxvYnAiID0gIkJVWVNFTExPQlAiLA0KICAgICAgICAgImJwcm9maXQiID0gIkJQUk9GSVQiLA0KICAgICAgICAgInNwcm9maXQiID0gIlNQUk9GSVQiLA0KICAgICAgICAgIm9icGJlZ2luIiA9ICJPQlBCRUdJTiIsDQogICAgICAgICAib2JwZW5kIiA9ICJPQlBFTkQiLA0KICAgICAgICAgIm9icGJlZ2lubm8iID0gIk9CUEJFR0lOTk8iLA0KICAgICAgICAgIm9icGVuZG5vIiA9ICJPQlBFTkROTyIsDQogICAgICAgICAib2JwbWlucHJpY2UiID0gIk9CUE1JTlBSSUNFIiwNCiAgICAgICAgICJvYnBtYXhwcmljZSIgPSAiT0JQTUFYUFJJQ0UiLA0KICAgICAgICAgIm9icG1pbnRyYWRlcHJpY2UiID0gIk9CUE1JTlRSQURFUFJJQ0UiLA0KICAgICAgICAgIm9icG1heHRyYWRlcHJpY2UiID0gIk9CUE1BWFRSQURFUFJJQ0UiLA0KICAgICAgICAgImJwcm9maXQiID0gIkJQUk9GSVQiLA0KICAgICAgICAgInNwcm9maXQiID0gIlNQUk9GSVQiLA0KICAgICAgICAgInRyYWRlc25vdHJhZGVzIiA9ICJUUkFERVNOT1RSQURFUyIpICU+JSANCiAgZGlzdGluY3QoKQ0Kb2JwX2N1bV9hdHRzX2VuaF9kZg0KYGBgDQoNCmBgYHtyfQ0KdGRfdm9sX3N1bV9kZiA8LSBvYnBfY3VtX2F0dHNfZW5oX2RmICU+JSANCiAgZ3JvdXBfYnkoc2VjY29kZSwgZGRhdGUpICU+JSANCiAgc3VtbWFyaXNlKHRkdm9sc3VtID0gc3VtKHRyYWRldm9sKSkNCg0Kb2JwX2N1bV9hdHRzX2VuaF92b2xhcnJhbmdlZF9kZiA8LSBsZWZ0X2pvaW4ob2JwX2N1bV9hdHRzX2VuaF9kZiwNCiAgICAgICAgICB0ZF92b2xfc3VtX2RmLA0KICAgICAgICAgIGJ5ID0gYygic2VjY29kZSIsICJkZGF0ZSIpKSAlPiUgDQogIG11dGF0ZShvYnBzaGFyZWludGQgPSB0cmFkZXZvbCAvIHRkdm9sc3VtKSAlPiUgDQogIHNlbGVjdCgtdGR2b2xzdW0pICU+JSANCiAgYXJyYW5nZShzZWNjb2RlLCBkZGF0ZSwgZGVzYyhvYnBzaGFyZWludGQpKQ0KDQpvYnBfY3VtX2F0dHNfZW5oX3ZvbGFycmFuZ2VkX2RmDQpgYGANCg0KYGBge3J9DQpvcHRpb25zKGRpZ2l0cy5zZWNzID0gMykNCm9icF9jdW1fYXR0c19lbmhfdm9sYXJyYW5nZWRfZGYgJT4lDQogIHdyaXRlX2NzdigiLi4vb3JkZXItYm9vay1wbG90LWZpbmQvY3VtX2Vycm9ycy9yZXNvdXJjZXMvZm9yX3dlYl9hcHAvb2JwX2N1bV9hdHRzX2VuaF9kZi5jc3YiLA0KICAgICAgICAgICAgbmEgPSAiIikNCmBgYA0KDQpgYGB7cn0NCm9yZGVyX2F0dHNfY3Vtc3Vtc19lbmgyX2RmIDwtIG9yZGVyX2F0dHNfY3Vtc3Vtc19lbmhhbmNlZF9kZiAlPiUgDQogIG11dGF0ZShwY29sb3IgPSBpZl9lbHNlKEFUVCA9PSAiQk9WT0wiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgImFxdWFtYXJpbmUiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgaWZfZWxzZShBVFQgPT0gIlNPVk9MIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY29yYWwiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIjMDA0NDgxIikpLA0KICAgICAgICAgcHNoYXBlID0gNEwsDQogICAgICAgICBwc2l6ZSA9IDAuNSkNCm9yZGVyX2F0dHNfY3Vtc3Vtc19lbmgyX2RmDQpgYGANCg0KYGBge3J9DQpvcmRlcl9hdHRzX2N1bXN1bXNfZW5oNF9kZiA8LSBvcmRlcl9hdHRzX2N1bXN1bXNfZW5oMl9kZiAlPiUgDQogIGFycmFuZ2UoU0VDQ09ERSwgREFURSwgTk8pICU+JSANCiAgcmVuYW1lKCJubm8iID0gIk5PIiwNCiAgICAgICAgICJzZWNjb2RlIiA9ICJTRUNDT0RFIiwNCiAgICAgICAgICJkYXRldGltZW1sbHMiID0gIkRBVEVUSU1FTUxMUyIsDQogICAgICAgICAicHJpY2UiID0gIlBSSUNFIiwNCiAgICAgICAgICJ0cmFkZXByaWNlIiA9ICJUUkFERVBSSUNFIiwNCiAgICAgICAgICJ2b2x1bWUiID0gIlZPTFVNRSIsDQogICAgICAgICAiZGRhdGUiID0gIkRBVEUiLA0KICAgICAgICAgInR0aW1lX3MiID0gIlRJTUVfUyIsDQogICAgICAgICAib2JwbG90bm8iID0gIk9CUExPVE5PIiwNCiAgICAgICAgICJhdHQiID0gIkFUVCIsDQogICAgICAgICAidmFsIiA9ICJWQUwiLA0KICAgICAgICAgInNoYXJlYmFsIiA9ICJTSEFSRUJBTCIpICU+JSANCiAgc2VsZWN0KC1CUFJPRklULCAtU1BST0ZJVCwgLU9CUE1JTlRQUklDRSwgLU9CUE1BWFRQUklDRSkNCiMgb3B0aW9ucyhkaWdpdHMuc2VjcyA9IDMpDQpvcmRlcl9hdHRzX2N1bXN1bXNfZW5oNF9kZiAlPiUNCiAgd3JpdGVfY3N2KCIuLi9vcmRlci1ib29rLXBsb3QtZmluZC9jdW1fZXJyb3JzL3Jlc291cmNlcy9mb3Jfd2ViX2FwcC9vcmRlcl9hdHRzX2N1bXN1bXNfZW5oNF9kZi5jc3YiLA0KICAgICAgICAgICAgbmEgPSAiIikNCm9yZGVyX2F0dHNfY3Vtc3Vtc19lbmg0X2RmDQpgYGANCg0KYGBge3J9DQpvcmRlcl9hdHRzX2N1bXN1bXNfZW5oNF9kZiAlPiUgDQogIGZpbHRlcihvYnBsb3RubyA9PSA0ODg1MSwgYXR0ID09ICJTVFZPTCIpICU+JSANCiAgc2VsZWN0KG5ubywgcHJpY2UsIGF0dCwgdHJhZGVwcmljZSwgc29icCwgYm9icCkNCmBgYA0KDQo=